package com.xingkeduo.service.cms.activity.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.xingkeduo.dao.TActivityDaysMapper;
import com.xingkeduo.dao.TActivityDaysMapperSpec;
import com.xingkeduo.dao.TActivityMapper;
import com.xingkeduo.model.example.TActivityDaysExample;
import com.xingkeduo.model.example.TActivityExample;
import com.xingkeduo.model.example.TActivityExample.Criteria;
import com.xingkeduo.model.param.ActivityDaysParam;
import com.xingkeduo.model.param.ActivityParam;
import com.xingkeduo.model.param.ActivityParam.ActivityModeEnum;
import com.xingkeduo.model.param.ActivityParam.ActivityTypeEnum;
import com.xingkeduo.model.param.ActivityParam.PreferentialModeEnum;
import com.xingkeduo.model.param.MarketingParam.MarketingCouponStatusEnum;
import com.xingkeduo.model.param.MarketingParam.MarketingStatusEnum;
import com.xingkeduo.model.po.TActivity;
import com.xingkeduo.model.po.TActivityDays;
import com.xingkeduo.model.po.TActivityWithBLOBs;
import com.xingkeduo.model.vo.ActivityDaysResponseVo;
import com.xingkeduo.model.vo.ActivityResponseVo;
import com.xingkeduo.service.cms.activity.ActivityMarketingTemplateService;
import com.xingkeduo.service.cms.marketing.InventoryService;
import com.xingkeduo.service.consume.UserService;
import com.xingkeduo.util.Constant;
import com.xingkeduo.util.DateUtils;
import com.xingkeduo.util.StringUtils;
import com.xingkeduo.util.tool.ResponseMessage;

@Service
public class ActivityMarketingTemplateServiceImpl implements ActivityMarketingTemplateService {

	@Autowired
	InventoryService inventoryService;
	@Autowired
	TActivityDaysMapperSpec tActivityDaysMapperSpec;
	@Autowired
	TActivityDaysMapper tActivityDaysMapper;
	@Autowired
	TActivityMapper tActivityMapper;
	@Autowired
	UserService userService;

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public ResponseMessage saveOrUpdateActivityByTemplate(ActivityParam activityTemplate) {
		// 实例化activity对象
		TActivityWithBLOBs activity = buildNewActivity(activityTemplate);
		// 新建活动
		if (activity.getId() == null) {
			activity.setCreateTime(new Date());
			activity.setSurplusQuantity(activity.getStockQuantity());
			tActivityMapper.insertSelective(activity);
			activityTemplate.setId(activity.getId());
			// 增加活动时间
			saveAndUpdateActivityTime(null, activityTemplate);
			return ResponseMessage.ok(activity);
		}
		// 老活动编辑
		TActivityWithBLOBs oldTActivity = tActivityMapper.selectByPrimaryKey(activity.getId());
		if (oldTActivity.getStockQuantity().intValue() > activityTemplate.getStockQuantity().intValue()) {
			return ResponseMessage.error("库存不能低于初始设置", 500);
		}
		if (activity.getStockQuantity() != null
				&& oldTActivity.getStockQuantity().intValue() != activity.getStockQuantity().intValue()) {
			activity.setSurplusQuantity(oldTActivity.getSurplusQuantity().intValue()
					+ activity.getStockQuantity().intValue() - oldTActivity.getStockQuantity().intValue());
		}
		// 修改活动时间
		saveAndUpdateActivityTime(oldTActivity, activityTemplate);
		tActivityMapper.updateByPrimaryKeySelective(activity);
		return ResponseMessage.ok(activity);
	}

	private void saveAndUpdateActivityTime(TActivityWithBLOBs oldTActivity, ActivityParam activityTemplate) {
		// 新增操作
		if (oldTActivity == null) {
			// 批量插入活动时间
			if (!CollectionUtils.isEmpty(activityTemplate.getActivityDaysParams())) {
				tActivityDaysMapperSpec.insertActivityByBatch(activityTemplate);
			}
			return;
		}
		// 修改操作
		List<Long> activityDaysList = new ArrayList<Long>();
		for (ActivityDaysParam activityDaysParam : activityTemplate.getActivityDaysParams()) {
			// 1.1新增活动情况
			if (activityDaysParam.getId() == null) {
				// 1.1.1新增活动时间
				TActivityDays activityDays = new TActivityDays(oldTActivity.getId(), oldTActivity.getActivityMode(),
						activityDaysParam.getDayids(), activityDaysParam.getStartTime(), activityDaysParam.getEndTime(),
						activityDaysParam.getActivityAmount(), Constant.STATUS_YES, activityTemplate.getCreateBy(),
						new Date(), activityTemplate.getCreateBy(), new Date());
				tActivityDaysMapper.insertSelective(activityDays);
				activityDaysList.add(activityDays.getId());
			}
			// 1.2更新活动情况
			if (activityDaysParam.getId() != null) {
				// 1.2.1更新活动时间
				TActivityDays newTActivityDays = new TActivityDays();
				BeanUtils.copyProperties(activityDaysParam, newTActivityDays);
				tActivityDaysMapper.updateByPrimaryKeySelective(newTActivityDays);
				activityDaysList.add(activityDaysParam.getId());
			}
		}
		// 2 删除活动情况
		if (!CollectionUtils.isEmpty(activityDaysList)) {
			TActivityDays record = new TActivityDays();
			record.setStatus(Constant.STATUS_NO_2);
			TActivityDaysExample tActivityDaysExample = new TActivityDaysExample();
			tActivityDaysExample.createCriteria().andActivityTypeEqualTo(oldTActivity.getActivityMode())
					.andStatusEqualTo(Constant.STATUS_YES).andActivityIdEqualTo(oldTActivity.getId())
					.andIdNotIn(activityDaysList);
			tActivityDaysMapper.updateByExampleSelective(record, tActivityDaysExample);
		}
	}

	private TActivityWithBLOBs buildNewActivity(ActivityParam activityTemplate) {
		TActivityWithBLOBs activity = new TActivityWithBLOBs();
		BeanUtils.copyProperties(activityTemplate, activity);
		if (activityTemplate.getId() == null && activityTemplate.getStartTime() == null) {
			activity.setStartTime(DateUtils.getCurdate());
		}
		if (activityTemplate.getId() == null && activityTemplate.getEndTime() == null) {
			activity.setEndTime(DateUtils.addSomeMonths(activity.getStartTime(), 12));
		}
		String endTimeStr = DateUtils.formatDate(DateUtils.getCurdate(activity.getEndTime()), DateUtils.DATE_FORMAT_EN)
				+ "235959";
		activity.setEndTime(DateUtils.parseDate(endTimeStr));
		activity.setUpdateTime(new Date());
		if (StringUtils.isNotBlank(activityTemplate.getStoreIds())) {
			activity.setStoreIds(activityTemplate.getStoreIds().replaceAll(",,", ","));
		}
		activity.setCreateBy(activityTemplate.getCreateBy());
		activity.setUpdateBy(activityTemplate.getUpdateBy());
		if (activityTemplate.getId() != null) {
			activity.setCreateBy(null);
		}
		return activity;
	}

	private TActivityWithBLOBs buildNewActivityStatus(ActivityParam activityTemplate) {
		TActivityWithBLOBs activity = new TActivityWithBLOBs();
		BeanUtils.copyProperties(activityTemplate, activity);
		activity.setUpdateTime(new Date());
		if (activity.getId() != null) {
			activity.setCreateBy(null);
		}
		return activity;
	}

	@Override
	public ResponseMessage queryActivityById(Long activityTemplateId) {
		TActivityWithBLOBs activity = tActivityMapper.selectByPrimaryKey(activityTemplateId);
		// 赋值活动时间
		ActivityResponseVo responseVo = new ActivityResponseVo();
		BeanUtils.copyProperties(activity, responseVo);
		if (StringUtils.isNotBlank(responseVo.getStoreIds())) {
			String storeIds = responseVo.getStoreIds();
			if (storeIds.startsWith("0,")) {
				storeIds = storeIds.substring(2, storeIds.length());
			}
			if (storeIds.endsWith(",0")) {
				storeIds = storeIds.substring(0, storeIds.length() - 2);
			}
			responseVo.setStoreIds(storeIds);
		}
		if (activity.getPreferentialMode().equals(PreferentialModeEnum.DISCOUNT.getCode())) {
			responseVo.setActivityAmount(responseVo.getActivityAmount().multiply(BigDecimal.valueOf(10)).setScale(1,
					BigDecimal.ROUND_HALF_DOWN));
		}
		TActivityDaysExample example = new TActivityDaysExample();
		example.createCriteria().andActivityIdEqualTo(activityTemplateId)
				.andActivityTypeEqualTo(activity.getActivityMode()).andStatusEqualTo(Constant.STATUS_YES);
		List<ActivityDaysResponseVo> activityDaysResponseList = new ArrayList<ActivityDaysResponseVo>();
		List<TActivityDays> activityDaysList = tActivityDaysMapper.selectByExample(example);
		for (TActivityDays activityDays : activityDaysList) {
			ActivityDaysResponseVo vo = new ActivityDaysResponseVo();
			BeanUtils.copyProperties(activityDays, vo);
			activityDaysResponseList.add(vo);
		}
		responseVo.setActivityDays(activityDaysResponseList);
		if (responseVo.getStartTime().after(new Date())) {
			responseVo.setActivityStatus(MarketingCouponStatusEnum.UN_START.getType());
		} else if (responseVo.getEndTime().before(new Date())) {
			responseVo.setActivityStatus(MarketingCouponStatusEnum.OVER.getType());
		} else {
			responseVo.setActivityStatus(MarketingCouponStatusEnum.RUNING.getType());
		}
		if(ActivityModeEnum.HAIRDRESSER.getCode() == activity.getActivityMode().intValue() 
				&& activity.getHairStyleId() != null){
			Map<String, String> returnMap = userService.queryCraftsmanById(activity.getHairStyleId());
			if (MapUtils.isNotEmpty(returnMap)) {
				responseVo.setHairStyleInfo(activity.getHairStyleId() + "_" + returnMap.get("name"));
			}
		}
		return ResponseMessage.ok(responseVo);
	}

	@Override
	public ResponseMessage updateActivityStatusById(ActivityParam activityTemplate) {
		// 上架前需验证是否有服务冲突
		if (activityTemplate.getStatus().intValue() == MarketingStatusEnum.UP.getCode()) {
			// 门店-门店只有分流不可同时上架
			if (activityTemplate.getActivityMode().intValue() == ActivityModeEnum.STORE.getCode()) {
				ResponseMessage message = verifyStoreBypassFlow(activityTemplate);
				if (message.getStatus() != ResponseMessage.ok().getStatus()) {
					return message;
				}
			// 发型师-发型师只能同时有一个活动上架
			} else if (activityTemplate.getActivityMode().intValue() == ActivityModeEnum.HAIRDRESSER.getCode()) {
				ResponseMessage message = verifyHairdresserBypassFlow(activityTemplate);
				if (message.getStatus() != ResponseMessage.ok().getStatus()) {
					return message;
				}
			}
		}
		TActivityWithBLOBs activity = buildNewActivityStatus(activityTemplate);
		tActivityMapper.updateByPrimaryKeySelective(activity);
		return ResponseMessage.ok("修改状态成功");
	}

	private ResponseMessage verifyHairdresserBypassFlow(ActivityParam activityTemplate) {
		// 查询待上架活动
		TActivityWithBLOBs activity = tActivityMapper.selectByPrimaryKey(activityTemplate.getId());
		if (activity.getActivityMode().intValue() != ActivityModeEnum.HAIRDRESSER.getCode()) {
			return ResponseMessage.error("操作业务不合法", 500);
		}
		// 发型师支付活动-只需要验证该用户在设置门店下同一时间段内是否存在其他活动
		if (activity.getActivityType().equalsIgnoreCase(ActivityTypeEnum.PAYMENT.getStatusType())) {
			// 验证该发型师活动在设置店铺下的唯一性【确定发型师在店铺下相同时间内没有其他活动】
			return veriftHairdresserHasOnlyActivity(activity);
		}
		// 发型师分流活动-需验证发型师是否在相同时间段内是否存在其他活动，并且设置的门店是否有分流活动
		if (activity.getActivityType().equalsIgnoreCase(ActivityTypeEnum.BYPASS_FLOW.getStatusType())) {
			// 验证该发型师活动在设置店铺下的唯一性【确定发型师在店铺下相同时间内没有其他活动】
			ResponseMessage message = veriftHairdresserHasOnlyActivity(activity);
			if (message.getStatus() != ResponseMessage.ok().getStatus()) {
				return message;
			}
			// 验证该店铺下分流活动的唯一性【确定店铺下相同时间内没有其他分流活动】
			return verifyStoreHasOnlyActivity(activity);
		}

		return ResponseMessage.ok();
	}

	// 验证该发型师活动在设置店铺下的唯一性【确定发型师在店铺下相同时间内没有其他活动】
	private ResponseMessage veriftHairdresserHasOnlyActivity(TActivityWithBLOBs activity) {
		TActivityExample example = new TActivityExample();
		example.createCriteria().andHairStyleIdEqualTo(activity.getHairStyleId())
				.andActivityModeEqualTo(activity.getActivityMode()).andStatusEqualTo(MarketingStatusEnum.UP.getCode())
				.andStartTimeLessThanOrEqualTo(activity.getEndTime())
				.andEndTimeGreaterThanOrEqualTo(activity.getStartTime());
		if (activity.getStoreIds().equals("0")) {
			int count = tActivityMapper.countByExample(example);
			if (count > 0) {
				return ResponseMessage.error("该发型师已在门店上架活动，不能再上架", 500);
			}
		}
		String storeIds = activity.getStoreIds();
		if (StringUtils.isBlank(storeIds)) {
			return ResponseMessage.error("该活动未指定门店", 500);
		}
		if (storeIds.startsWith(",")) {
			storeIds = storeIds.substring(1, storeIds.length());
		}
		if (StringUtils.isBlank(storeIds)) {
			return ResponseMessage.error("该活动未指定门店", 500);
		}
		String[] storeidArray = storeIds.split(",");
		List<TActivity> activityList = tActivityMapper.selectByExample(example);
		for (TActivity oldActivity : activityList) {
			if (oldActivity.getStoreIds().equals("0")) {
				return ResponseMessage.error("该发型师已在门店上架活动，不能再上架", 500);
			}
			int arraySize = storeidArray.length;
			for (int i = 0; i < arraySize; i++) {
				if (oldActivity.getStoreIds().contains("," + storeidArray[i] + ",")) {
					return ResponseMessage.error("该发型师已在门店上架活动，不能再上架", 500);
				}
			}
		}
		return ResponseMessage.ok();
	}

	private ResponseMessage verifyStoreBypassFlow(ActivityParam activityTemplate) {
		// 查询待上架活动
		TActivityWithBLOBs activity = tActivityMapper.selectByPrimaryKey(activityTemplate.getId());
		if (!activity.getActivityType().equalsIgnoreCase(ActivityTypeEnum.BYPASS_FLOW.getStatusType())) {
			return ResponseMessage.ok("非分流活动不需校验-success");
		}
		if (activity.getActivityMode().intValue() != ActivityModeEnum.STORE.getCode()) {
			return ResponseMessage.error("操作业务不合法", 500);
		}
		return verifyStoreHasOnlyActivity(activity);
	}

	private ResponseMessage verifyStoreHasOnlyActivity(TActivityWithBLOBs activity) {
		String storeIds = activity.getStoreIds();
		if (StringUtils.isBlank(storeIds)) {
			return ResponseMessage.error("该活动未指定门店", 500);
		}
		if (storeIds.startsWith(",")) {
			storeIds = storeIds.substring(1, storeIds.length());
		}
		if (StringUtils.isBlank(storeIds)) {
			return ResponseMessage.error("该活动未指定门店", 500);
		}
		// 查询所有活动
		List<TActivity> activityList;
		if (activity.getActivityMode().intValue() == ActivityModeEnum.STORE.getCode()) {
			activityList = verifyStoreAndGetActivityList(activity);
		} else {
			activityList = verifyHairdresserAndGetActivityList(activity);
		}
		if (CollectionUtils.isEmpty(activityList)) {
			return ResponseMessage.ok();
		}
		String[] storeidArray = storeIds.split(",");
		for (TActivity oldActivity : activityList) {
			if (oldActivity.getStoreIds().equals("0")) {
				return ResponseMessage.error("该门店已上架同等活动，不能再上架", 500);
			}
			int arraySize = storeidArray.length;
			for (int i = 0; i < arraySize; i++) {
				if (oldActivity.getStoreIds().contains("," + storeidArray[i] + ",")) {
					return ResponseMessage.error("该门店已上架同等活动，不能再上架", 500);
				}
			}
		}
		return ResponseMessage.ok();
	}

	private List<TActivity> verifyStoreAndGetActivityList(TActivityWithBLOBs activity) {
		// 门店-验证该活动是否已有全门店支持
		TActivityExample example = new TActivityExample();
		Criteria criteria = example.createCriteria();
		criteria.andActivityTypeEqualTo(activity.getActivityType().toUpperCase())
				.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andStartTimeLessThanOrEqualTo(activity.getEndTime())
				.andEndTimeGreaterThanOrEqualTo(activity.getStartTime());
		if (activity.getStoreIds().equals("0")) {
			if (tActivityMapper.countByExample(example) > 0) {
				throw new RuntimeException("所有门店都已上架同等活动，不能再上架");
			}
		}
		List<TActivity> activityList = tActivityMapper.selectByExample(example);
		return activityList;
	}

	private List<TActivity> verifyHairdresserAndGetActivityList(TActivityWithBLOBs activity) {
		List<TActivity> returnList = new ArrayList<>();
		// 发型师-验证该发型师是否在该门店有同等活动
		TActivityExample hairExample = new TActivityExample();
		Criteria hiarCriteria = hairExample.createCriteria();
		hiarCriteria.andActivityTypeEqualTo(activity.getActivityType().toUpperCase())
				.andActivityModeEqualTo(ActivityModeEnum.HAIRDRESSER.getCode())
				.andHairStyleIdEqualTo(activity.getHairStyleId()).andStatusEqualTo(MarketingStatusEnum.UP.getCode())
				.andStartTimeLessThanOrEqualTo(activity.getEndTime())
				.andEndTimeGreaterThanOrEqualTo(activity.getStartTime());
		// 门店-验证该门店是否有同等活动
		TActivityExample storeExample = new TActivityExample();
		Criteria storeCriteria = storeExample.createCriteria();
		storeCriteria.andActivityTypeEqualTo(activity.getActivityType().toUpperCase())
				.andActivityModeEqualTo(ActivityModeEnum.STORE.getCode())
				.andStatusEqualTo(MarketingStatusEnum.UP.getCode()).andStartTimeLessThanOrEqualTo(activity.getEndTime())
				.andEndTimeGreaterThanOrEqualTo(activity.getStartTime());
		if (activity.getStoreIds().equals("0")) {
			if (tActivityMapper.countByExample(hairExample) > 0) {
				throw new RuntimeException("所有门店都已上架同等活动，不能再上架");
			}
			if (tActivityMapper.countByExample(storeExample) > 0) {
				throw new RuntimeException("所有门店都已上架同等活动，不能再上架");
			}
		}
		List<TActivity> hairActivityList = tActivityMapper.selectByExample(hairExample);
		if (!CollectionUtils.isEmpty(hairActivityList)) {
			returnList.addAll(hairActivityList);
		}
		List<TActivity> storeActivityList = tActivityMapper.selectByExample(storeExample);
		if (!CollectionUtils.isEmpty(storeActivityList)) {
			returnList.addAll(storeActivityList);
		}
		return returnList;
	}

	@Override
	public ResponseMessage queryActivityByTemplate(ActivityParam activityTemplate) {
		TActivityExample example = new TActivityExample();
		Criteria criteria = example.createCriteria();
		if (activityTemplate.getActivityMode() != null) {
			criteria.andActivityModeEqualTo(activityTemplate.getActivityMode());
		}
		// 活动Id,活动名称
		if (StringUtils.isNumeric(activityTemplate.getActivityInfo())) {
			criteria.andIdEqualTo(Long.valueOf(activityTemplate.getActivityInfo()));
		} else if (StringUtils.isNotBlank(activityTemplate.getActivityInfo())) {
			criteria.andNameLike("%" + activityTemplate.getActivityInfo() + "%");
		}
		// 发型师Id
		if (StringUtils.isNumeric(activityTemplate.getHairStyleInfo())) {
			criteria.andHairStyleIdEqualTo(Long.valueOf(activityTemplate.getHairStyleInfo()));
		}
		// 领取范围
		if (activityTemplate.getReceiveType() != null) {
			criteria.andReceiveTypeEqualTo(activityTemplate.getReceiveType());
		}
		// 适用门店
		if (StringUtils.isNotBlank(activityTemplate.getStoreIds())) {
			criteria.andStoreIdsLike("%," + activityTemplate.getStoreIds() + ",%");
		}
		// 活动状态
		if (StringUtils.isNotBlank(activityTemplate.getActivityStatus())) {
			MarketingCouponStatusEnum marketCouponStatusEnum = MarketingCouponStatusEnum
					.parse(activityTemplate.getActivityStatus());
			switch (marketCouponStatusEnum) {
			case UN_START:// 未开始˙
				criteria.andStartTimeGreaterThan(new Date());
				break;
			case RUNING:// 进行中
				criteria.andStartTimeLessThan(new Date());
				criteria.andEndTimeGreaterThan(new Date());
				break;
			case OVER:// 已结束
				criteria.andEndTimeLessThan(new Date());
				break;
			default:
				break;
			}
		}
		// 活动类型
		if (StringUtils.isNotBlank(activityTemplate.getActivityType())) {
			criteria.andActivityTypeEqualTo(activityTemplate.getActivityType());
		}
		// 上下架
		if (activityTemplate.getStatus() != null) {
			criteria.andStatusEqualTo(activityTemplate.getStatus());
		}
		example.setOrderByClause(" id desc");
		PageHelper.startPage(activityTemplate.getPageNum(), activityTemplate.getPageSize());
		List<TActivityWithBLOBs> activityList = tActivityMapper.selectByExampleWithBLOBs(example);
		PageInfo<TActivityWithBLOBs> page = new PageInfo<>(activityList);

		PageInfo<ActivityResponseVo> pageReturn = new PageInfo<>();
		BeanUtils.copyProperties(page, pageReturn);
		List<ActivityResponseVo> returnList = Lists.transform(activityList,
				new Function<TActivityWithBLOBs, ActivityResponseVo>() {
					@Override
					public ActivityResponseVo apply(TActivityWithBLOBs history) {
						ActivityResponseVo responseVo = new ActivityResponseVo();
						BeanUtils.copyProperties(history, responseVo);
						if (ActivityModeEnum.STORE.getCode() == history.getActivityMode().intValue()) {
							return responseVo;
						}
						if(ActivityModeEnum.HAIRDRESSER.getCode() == history.getActivityMode().intValue() 
								&& history.getHairStyleId() != null){
							Map<String, String> returnMap = userService.queryCraftsmanById(history.getHairStyleId());
							if (MapUtils.isNotEmpty(returnMap)) {
								responseVo.setHairStyleInfo(history.getHairStyleId() + "_" + returnMap.get("name"));
							}
						}
						return responseVo;
					}
				});
		pageReturn.setList(returnList);
		return ResponseMessage.ok(pageReturn);
	}
}
